import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, CancelTokenSource } from 'axios';
import { debounce } from 'lodash-es';
import { ElMessage } from 'element-plus'; // 如果使用Element Plus UI库
import { getItem } from './componen';
import router from '../router';
// 创建 Axios 实例
const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API, // 使用环境变量来设置基础URL
  timeout: 50000, // 请求超时时间
});

// 存储取消请求的 token source
const pendingRequests: Map<string, CancelTokenSource> = new Map();
// 取消重复请求的方法
function cancelPendingRequests(url: string) {
  if (pendingRequests.has(url)) {
    const source = pendingRequests.get(url)!;
    source.cancel('有新的请求，操作已取消');
    pendingRequests.delete(url);
  }
}

// 添加请求到待处理队列
function addPendingRequest(config: AxiosRequestConfig) {
  if (config.url) {
    cancelPendingRequests(config.url); // 取消相同 URL 的旧请求
    const source = axios.CancelToken.source();
    pendingRequests.set(config.url!, source);
    config.cancelToken = source.token;
  }
}

// 清除请求
function clearPendingRequest(config: AxiosRequestConfig) {
  if (config.url) {
    pendingRequests.delete(config.url!);
  }
}

// 请求拦截器
service.interceptors.request.use(
  (config: any) => {
    // 在发送请求之前做些什么
    //判断是否允许重复发送
    if (!config.isRepeat) {
      addPendingRequest(config);
    }
    const apiToken = getItem('apiToken');
    if (!apiToken) {
      router.push('/login');
    }
    // 让每个请求携带 token
    config.headers.apiToken = apiToken;
    config.headers.loginToken = getItem('loginToken');
    config.headers.authorization = `Bearer ${getItem('authenticationToken')}`;
    return config;
  },
  (error) => {
    // 对请求错误做些什么
    return Promise.reject(error);
  },
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    // 对响应数据做点什么
    const res = response.data;
    if (res.state === 100) {
      ElMessage({
        message: '登录已超时,请重新登录',
        type: 'error',
      });
      router.push('/login');
      return Promise.reject(response.data);
    } else if (res.state !== 0 && !!res.errorMessage) {
      ElMessage({
        message: res.errorMessage,
        type: 'error',
      });
      return Promise.reject(response.data);
    } else {
      // 清除请求
      clearPendingRequest(response.config);
      if (!!res.data) {
        return !!res.data.data ? res.data.data : res.data;
      }
      return res;
    }
  },
  (error) => {
    // 对响应错误做点什么
    if (!axios.isCancel(error)) {
      ElMessage.error(error.message || '未设置错误提示');
    }
    return Promise.reject(error);
  },
);

// 防抖函数包装器
function debounceRequest<T extends (...args: any[]) => Promise<any>>(func: T, wait?: number): T {
  return debounce(func, wait || 500) as unknown as T;
}

export default service;
export { debounceRequest };
